package com.wsd.serviceImpl;/*
 *
 *  *  Copyright © 2020 CIB Co.Ltd
 *  *  * All right reserved
 *  *  * Auther:7ason
 *  *
 *
 */

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.wsd.CallableTask.WxOpenIdTaskQuery;
import com.wsd.common.NetworkUtil;
import com.wsd.common.Result;
import com.wsd.constant.ConstantUtil;
import com.wsd.constant.ResultCode;
import com.wsd.dao.WsdCifIdMappingMapper;
import com.wsd.domain.WsdCifIdMapping;
import com.wsd.service.WechatService;
import com.wsd.vo.SubscribeMessageVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
import java.util.logging.Logger;


@Service("WechatService")
public class WechatServiceImpl  implements WechatService {
    private static String ACCESS_TOKEN = "null";//微信小程序服务调用的ACCESS_TOKEN
    private static long ACCESS_TOKEN_EXPIRES_AT = 0;//微信小程序服务调用的ACCESS_TOKEN过期时间
    private static final String  TEMPLATE_ID_QUOTA = "6GH0-plqVm1Y6FeuT3hRWT9w1-moER6dM4O9rZ3Pxks";//授信TEMPID
    private static final String  TEMPLATE_ID_LOAN = "y7k6__v1eHh_4pPaxOIP1wu0f0jAFz8ElrEnTfMT7FQ";//提现TEMPID
    private static final String  TEMPLATE_ID_OVERDUE = "Xd0R-tdyowqapZuQj5LDBOqYAVyZqLEngdppj6C7drw";//逾期TEMPID

    //获取线程池对象
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Autowired
    private WsdCifIdMappingMapper wsdCifIdMappingMapper;

    /**
     * jscode换取openid
     * @param jscode
     */
    @Override
    public Result jscodeToWeixinSession(String jscode) {

        Result result = new Result();
        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session?appid="+ ConstantUtil.Public.WX_APPID +"&secret="+ ConstantUtil.Public.WX_SECRET +"&js_code="+jscode+"&grant_type=authorization_code";
        String openid = "null";
        try {
            String requestResult = NetworkUtil.sendGet(requestUrl);
            JSONObject resultJson = new JSONObject();
            resultJson = JSONObject.parseObject(requestResult);
            if(resultJson.getString("openid")!=null){
                result.setResultCode(ResultCode.SUCCESS);
                openid = resultJson.getString("openid");
                //处理注册/登陆
                JSONObject valueObject= new JSONObject();
                valueObject.put("openid",openid);
                result.setData(openid);

            }else{
                result.setResultCode(ResultCode.SYSTEM_INNER_ERROR);
                result.setResultMsg(resultJson.getString("errmsg"));
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setResultCode(ResultCode.SYSTEM_INNER_ERROR);
            result.setResultMsg("系统对接错误"+e.getLocalizedMessage());
        }


        return result;
    }



    /**
     * 下发授信额度的消息
     * @param openid 用户openid
     * @param result  审核结果（已通过，未通过，请注意）
     * @param info  审核内容
     */
    @Override
    public Result sendWechatMessageByQuota(String openid,String result,String info) {
        if(result.equals("已通过")||result.equals("未通过")||result.equals("请注意")){

        }else{
            result = "其他";
        }
        JSONObject dataObject = new JSONObject();


        JSONObject valueObject_1 = new JSONObject();
        valueObject_1.put("value",result);
        dataObject.put("phrase1",valueObject_1);

        JSONObject valueObject_2 = new JSONObject();
        valueObject_2.put("value",info);
        dataObject.put("thing2",valueObject_2);

        return  sendWechatMessage(openid,dataObject,"quota",TEMPLATE_ID_QUOTA);

    }
    /**
     * 下发放款的消息
     * @param openid 用户openid
     * @param amount  额度值
     * @param loanTime  提现时间
     */
    @Override
    public Result sendWechatMessageByLoan(String openid, int amount, LocalDateTime loanTime) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String timeString = formatter.format(loanTime);
        JSONObject dataObject = new JSONObject();


        JSONObject valueObject_1 = new JSONObject();
        valueObject_1.put("value",amount+"");
        dataObject.put("amount1",valueObject_1);

        JSONObject valueObject_2 = new JSONObject();
        valueObject_2.put("value",timeString);
        dataObject.put("time7",valueObject_2);

        return  sendWechatMessage(openid,dataObject,"loan",TEMPLATE_ID_LOAN);
    }

    /**
     * 下发逾期的消息
     * @param openid 用户openid
     * @param overdueTime
     */
    @Override
    public Result sendWechatMessageByOverdue(String openid,LocalDateTime overdueTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String timeString = formatter.format(overdueTime);
        JSONObject dataObject = new JSONObject();


        JSONObject valueObject_1 = new JSONObject();
        valueObject_1.put("value","微闪DAI");
        dataObject.put("thing1",valueObject_1);

        JSONObject valueObject_2 = new JSONObject();
        valueObject_2.put("value",timeString);
        dataObject.put("time2",valueObject_2);

        return  sendWechatMessage(openid,dataObject,"overdue",TEMPLATE_ID_OVERDUE);
    }

    /**
     * 根据userId查询WxOpenId
     *
     * @param userIdList
     * @return
     */
    @Override
    public List<String> queryOpenIds(List<String> userIdList) {
        List<String> ids = wsdCifIdMappingMapper.getWxOpenIdByUserId(userIdList);
        return ids;
    }


    /**
     * 刷新小程序全局唯一后台接口调用凭据（access_token）
     */
    private synchronized Result reFreshAccessToken() {
        Result result = new Result();

        String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ConstantUtil.Public.WX_APPID+"&secret="+ConstantUtil.Public.WX_SECRET;
        try {
            String requestResult = NetworkUtil.sendGet(requestUrl);
            JSONObject resultJson = JSONObject.parseObject(requestResult);
            if(resultJson.getString("access_token") != null){
                result.setResultCode(ResultCode.SUCCESS);
                String accessToken = resultJson.getString("access_token");
                int expiresIn = resultJson.getInteger("expires_in");
                ACCESS_TOKEN = accessToken;
                Date now = new Date();
                long nowTime = now.getTime()/1000;
                //计算ACCESS_TOKEN过期时间,-60秒为了时间更宽裕
                ACCESS_TOKEN_EXPIRES_AT = nowTime+expiresIn-60;
                result.setResultMsg(resultJson.getString("errmsg"));
            }else{
                result.setResultCode(ResultCode.SYSTEM_INNER_ERROR);
                result.setResultMsg(resultJson.getString("errmsg"));
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setResultCode(ResultCode.SYSTEM_INNER_ERROR);
            result.setResultMsg("系统对接错误");
        }



        return result;


    }


    /**
     * 下发小程序的服务消息推送
     * @param openid 用户openid
     * @param dataObject 模板信息内容
     * @param type 模板信息类型
     */
    private Result sendWechatMessage(String openid,JSONObject dataObject,String type,String templateId) {
        Result result = new Result();

        //判断ACCESS_TOKEN是否过期
        Date now = new Date();
        long nowTime = now.getTime()/1000;
        if(nowTime>ACCESS_TOKEN_EXPIRES_AT){
            Result reFreshAccessTokenResult =  reFreshAccessToken();
            if(reFreshAccessTokenResult.getResultCode()!=ResultCode.SUCCESS.getCode()){
                result.setResultCode(ResultCode.SYSTEM_INNER_ERROR);
                result.setResultMsg(reFreshAccessTokenResult.getResultMsg());
                return result;
            }
        }



        String requestUrl = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="+ACCESS_TOKEN;
        JSONObject requestJson = new JSONObject();
        requestJson.put("touser",openid);
        requestJson.put("template_id", templateId);
        requestJson.put("page", "pages/subscribeMessage/subscribeMessage?type="+type);
        requestJson.put("miniprogram_state", "trial");
        requestJson.put("data",dataObject);
        String requestData = requestJson.toString();
        try {
            String requestResult = NetworkUtil.sendPost(requestUrl,requestData);
            JSONObject resultJson = JSONObject.parseObject(requestResult);
            if(resultJson.getInteger("errcode") == 0){
                result.setResultCode(ResultCode.SUCCESS);
            }else{
                result.setResultCode(ResultCode.SYSTEM_INNER_ERROR);
                result.setResultMsg(resultJson.getString("errmsg"));
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setResultCode(ResultCode.SYSTEM_INNER_ERROR);
            result.setResultMsg("系统对接错误"+e.getLocalizedMessage());
        }

        return result;


    }

    /**
     * 根据userId列表 批量获取WxOpenId
     * 多线程查
     * @param userIdList
     * @return
     * zhangqizeng  2020 7 28
     */
    public List<String> batchGetWxOpenIdByUserId(List<String> userIdList){
        List<String> allTaskResult = new ArrayList<String>();

        //将userId分割 每组50个
        List<List<String>> userIdParts = Lists.partition(userIdList,50);

        //添加Task
        List<Callable<List<String>>> tasks = new ArrayList<>();
        for (List<String> part : userIdParts){
            WxOpenIdTaskQuery wxOpenIdTaskQuery = new WxOpenIdTaskQuery();
            wxOpenIdTaskQuery.setIds(part);
            tasks.add(wxOpenIdTaskQuery);
        }

        //每个任务结果都是future对象
        List<Future<List<String>>> futures = new ArrayList<>();
        for (Callable<List<String>> task : tasks){
            //提交任务
            futures.add(taskExecutor.submit(task));
        }

        // 遍历执行结果，准备正式执行（get）
        for (Future<List<String>> future : futures) {
            try {
                // 查询任务超过3s的直接弃掉（cancel取消任务）
                List<String> taskList =future.get(3000, TimeUnit.MILLISECONDS );
                if(!taskList.isEmpty()){
                    allTaskResult.addAll(taskList);
                }
            }catch (InterruptedException | ExecutionException | TimeoutException e){
                future.cancel(true);
            }
        }
        //关闭线程池
        taskExecutor.shutdown();
        return allTaskResult;
    }

    /**
     * zhangqizeng 2020 7 28
     * 异步下发消息,批量传入需要下发的用户openid和内容
     * @param subscribeMessageVOList
     */
    public void sendMessageAsyn(List<SubscribeMessageVO> subscribeMessageVOList){
        taskExecutor.initialize();
        int size = subscribeMessageVOList.size();
        for (int i=1;i<=size;i++){
            taskExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    //TODO  下发到小程序的消息
//                    sendWechatMessageByLoan(openIdList.get(i),1000,Time)
                }
            });


        }
    }

}